home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / misc / 40 / termcap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-07-17  |  6.8 KB  |  332 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* termcap.c - version 1.0.3 */
  3.  
  4. #include <stdio.h>
  5. #include "config.h"    /* for ROWNO and COLNO */
  6. #include "flag.h"    /* for flags.nonull */
  7. #ifndef MSDOS
  8. #define MSDOS
  9. #endif
  10. extern char *tgetstr(), *tgoto(), *getenv();
  11. extern long *alloc();
  12.  
  13. #ifndef lint
  14. extern            /* it is defined in libtermlib (libtermcap) */
  15. #endif lint
  16.     short ospeed;        /* terminal baudrate; used by tputs */
  17. static char tbuf[512];
  18. #ifdef DGK
  19. char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE, *HI, *HE;
  20. #else
  21. static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
  22. #endif DGK
  23. static char *VS, *VE;
  24. static int SG;
  25. static char PC = '\0';
  26. char *CD;        /* tested in pri.c: docorner() */
  27. int CO, LI;        /* used in pri.c and whatis.c */
  28.  
  29. #ifdef MSDOS
  30. static char tgotobuf[20];
  31. #define tgoto(fmt, x, y)    (sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf)
  32. #endif MSDOS
  33.  
  34. startup()
  35. {
  36. #ifdef MSDOS
  37.     HO = "\033H";
  38.     CL = "\033E";        /* the ANSI termcap */
  39.     CE = "\033K";
  40.     UP = "\033A";
  41.     CM = "\033Y%c%c";    /* used with function tgoto() */
  42.     ND = "\033C";
  43.     XD = "\033B";
  44.     BC = "\033D";
  45.     SO = "\033p";
  46.     SE = "\033q";
  47.     TI = "";
  48.     TE = "";
  49.     VS = "";
  50.     VE = "";
  51. #ifdef DGK
  52.     /* Both HI and HE have 4 characters.  The function let_to_name()
  53.      * in msdos.c uses this length when creating a buffer.  If you
  54.      * make HI and HE longer, you must also change the length of buf[]
  55.      * in let_to_name()
  56.      */
  57.     HI = "\033p";
  58.     HE = "\033q";
  59. #endif DGK
  60.     CD = "\033";
  61.     CO = COLNO;
  62.     LI = ROWNO;
  63. #else
  64.     register char *term;
  65.     register char *tptr;
  66.     char *tbufptr, *pc;
  67.  
  68.     tptr = (char *) alloc(1024);
  69.  
  70.     tbufptr = tbuf;
  71.     if(!(term = getenv("TERM")))
  72.         error("Can't get TERM.");
  73.     if(!strncmp(term, "5620", 4))
  74.         flags.nonull = 1;    /* this should be a termcap flag */
  75.     if(tgetent(tptr, term) < 1)
  76.         error("Unknown terminal type: %s.", term);
  77.     if(pc = tgetstr("pc", &tbufptr))
  78.         PC = *pc;
  79.     if(!(BC = tgetstr("bc", &tbufptr))) {    
  80.         if(!tgetflag("bs"))
  81.             error("Terminal must backspace.");
  82.         BC = tbufptr;
  83.         tbufptr += 2;
  84.         *BC = '\b';
  85.     }
  86.     HO = tgetstr("ho", &tbufptr);
  87.     CO = tgetnum("co");
  88.     LI = tgetnum("li");
  89.     if(CO < COLNO || LI < ROWNO+2)
  90.         setclipped();
  91.     if(!(CL = tgetstr("cl", &tbufptr)))
  92.         error("Hack needs CL.");
  93.     ND = tgetstr("nd", &tbufptr);
  94.     if(tgetflag("os"))
  95.         error("Hack can't have OS.");
  96.     CE = tgetstr("ce", &tbufptr);
  97.     UP = tgetstr("up", &tbufptr);
  98.     /* It seems that xd is no longer supported, and we should use
  99.        a linefeed instead; unfortunately this requires resetting
  100.        CRMOD, and many output routines will have to be modified
  101.        slightly. Let's leave that till the next release. */
  102.     XD = tgetstr("xd", &tbufptr);
  103. /* not:         XD = tgetstr("do", &tbufptr); */
  104.     if(!(CM = tgetstr("cm", &tbufptr))) {
  105.         if(!UP && !HO)
  106.             error("Hack needs CM or UP or HO.");
  107.         printf("Playing hack on terminals without cm is suspect...\n");
  108.         getret();
  109.     }
  110.     SO = tgetstr("so", &tbufptr);
  111.     SE = tgetstr("se", &tbufptr);
  112.     SG = tgetnum("sg");    /* -1: not fnd; else # of spaces left by so */
  113.     if(!SO || !SE || (SG > 0)) SO = SE = 0;
  114.     CD = tgetstr("cd", &tbufptr);
  115.     set_whole_screen();        /* uses LI and CD */
  116.     if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
  117.     free(tptr);
  118. #endif MSDOS
  119. }
  120.  
  121. start_screen()
  122. {
  123.     xputs(TI);
  124.     xputs(VS);
  125. }
  126.  
  127. end_screen()
  128. {
  129.     xputs(VE);
  130.     xputs(TE);
  131. }
  132.  
  133. /* Cursor movements */
  134. extern xchar curx, cury;
  135.  
  136. curs(x, y)
  137. register int x, y;    /* not xchar: perhaps xchar is unsigned and
  138.                curx-x would be unsigned as well */
  139. {
  140.  
  141.     if (y == cury && x == curx)
  142.         return;
  143.     if(!ND && (curx != x || x <= 3)) {    /* Extremely primitive */
  144.         cmov(x, y);            /* bunker!wtm */
  145.         return;
  146.     }
  147.     if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
  148.         nocmov(x, y);
  149.     else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
  150.         (void) putchar('\r');
  151.         curx = 1;
  152.         nocmov(x, y);
  153.     } else if(!CM) {
  154.         nocmov(x, y);
  155.     } else
  156.         cmov(x, y);
  157. }
  158.  
  159. nocmov(x, y)
  160. {
  161.     if (cury > y) {
  162.         if(UP) {
  163.             while (cury > y) {    /* Go up. */
  164.                 xputs(UP);
  165.                 cury--;
  166.             }
  167.         } else if(CM) {
  168.             cmov(x, y);
  169.         } else if(HO) {
  170.             home();
  171.             curs(x, y);
  172.         } /* else impossible("..."); */
  173.     } else if (cury < y) {
  174.         if(XD) {
  175.             while(cury < y) {
  176.                 xputs(XD);
  177.                 cury++;
  178.             }
  179.         } else if(CM) {
  180.             cmov(x, y);
  181.         } else {
  182.             while(cury < y) {
  183.                 xputc('\n');
  184.                 curx = 1;
  185.                 cury++;
  186.             }
  187.         }
  188.     }
  189.     if (curx < x) {        /* Go to the right. */
  190.         if(!ND) cmov(x, y); else    /* bah */
  191.             /* should instead print what is there already */
  192.         while (curx < x) {
  193.             xputs(ND);
  194.             curx++;
  195.         }
  196.     } else if (curx > x) {
  197.         while (curx > x) {    /* Go to the left. */
  198.             xputs(BC);
  199.             curx--;
  200.         }
  201.     }
  202. }
  203.  
  204. cmov(x, y)
  205. register x, y;
  206. {
  207.     xputs(tgoto(CM, x-1, y-1));
  208.     cury = y;
  209.     curx = x;
  210. }
  211.  
  212. xputc(c) char c; {
  213.     (void) fputc(c, stdout);
  214. }
  215.  
  216. xputs(s) char *s; {
  217. #ifdef MSDOS
  218.     fputs(s, stdout);
  219. #else
  220.     tputs(s, 1, xputc);
  221. #endif
  222. }
  223.  
  224. cl_end() {
  225.     if(CE)
  226.         xputs(CE);
  227.     else {    /* no-CE fix - free after Harold Rynes */
  228.         /* this looks terrible, especially on a slow terminal
  229.            but is better than nothing */
  230.         register cx = curx, cy = cury;
  231.  
  232.         while(curx < COLNO) {
  233.             xputc(' ');
  234.             curx++;
  235.         }
  236.         curs(cx, cy);
  237.     }
  238. }
  239.  
  240. clear_screen() {
  241.     xputs(CL);
  242.     curx = cury = 1;
  243. }
  244.  
  245. home()
  246. {
  247.     if(HO)
  248.         xputs(HO);
  249.     else if(CM)
  250.         xputs(tgoto(CM, 0, 0));
  251.     else
  252.         curs(1, 1);    /* using UP ... */
  253.     curx = cury = 1;
  254. }
  255.  
  256. standoutbeg()
  257. {
  258.     if(SO) xputs(SO);
  259. }
  260.  
  261. standoutend()
  262. {
  263.     if(SE) xputs(SE);
  264. }
  265.  
  266. backsp()
  267. {
  268.     xputs(BC);
  269.     curx--;
  270. }
  271.  
  272. bell()
  273. {
  274. #ifdef DGK
  275.     if (flags.silent) return;
  276. #endif DGK
  277.     (void) putchar('\007');        /* curx does not change */
  278.     (void) fflush(stdout);
  279. }
  280.  
  281. static short tmspc10[] = {        /* from termcap */
  282.     0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
  283. };
  284.  
  285. delay_output() {
  286.     /* delay 50 ms - could also use a 'nap'-system call */
  287.     /* BUG: if the padding character is visible, as it is on the 5620
  288.        then this looks terrible. */
  289. #ifdef MSDOS
  290.     /* simulate the delay with "cursor here" 5 times*/
  291.     register i;
  292.     for (i = 0; i < 5; i++)
  293.         cmov(curx, cury);
  294. #else
  295.     if(!flags.nonull)
  296.         tputs("50", 1, xputc);
  297.  
  298.         /* cbosgd!cbcephus!pds for SYS V R2 */
  299.         /* is this terminfo, or what? */
  300.         /* tputs("$<50>", 1, xputc); */
  301.  
  302.     else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
  303.         /* delay by sending cm(here) an appropriate number of times */
  304.         register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
  305.         register int i = 500 + tmspc10[ospeed]/2;
  306.  
  307.         while(i > 0) {
  308.             cmov(curx, cury);
  309.             i -= cmlen*tmspc10[ospeed];
  310.         }
  311.     }
  312. #endif MSDOS
  313. }
  314.  
  315. cl_eos()            /* free after Robert Viduya */
  316. {                /* must only be called with curx = 1 */
  317.  
  318.     if(CD)
  319.         xputs(CD);
  320.     else {
  321.         register int cx = curx, cy = cury;
  322.         while(cury <= LI-2) {
  323.             cl_end();
  324.             xputc('\n');
  325.             curx = 1;
  326.             cury++;
  327.         }
  328.         cl_end();
  329.         curs(cx, cy);
  330.     }
  331. }
  332.